package org.jeecg.modules.leave.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.IdentityService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.delegate.*;
import org.activiti.engine.repository.Model;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.JsonUtils;
import org.jeecg.modules.leave.entity.AgLeave;
import org.jeecg.modules.leave.mapper.AgLeaveMapper;
import org.jeecg.modules.leave.service.IAgLeaveService;
import org.jeecg.modules.lida.entity.GroupPO;
import org.jeecg.modules.lida.service.LidaService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.web.client.RestTemplate;

import java.time.LocalDate;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.*;

/**
 * @Description: ag_leave
 * @Author: jeecg-boot
 * @Date:   2020-05-18
 * @Version: V1.0
 */
@Service
@Slf4j
public class AgLeaveServiceImpl extends ServiceImpl<AgLeaveMapper, AgLeave> implements IAgLeaveService, JavaDelegate {
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private LidaService lidaService;
    @Autowired
    private IAgLeaveService agLeaveService;
    @Autowired
    private AgLeaveMapper agLeaveMapper;
    @Autowired
    private IdentityService identityservice;
    @Autowired
    private RuntimeService runtimeservice;
    @Autowired
    private TaskService taskService;
    @Autowired
    private RepositoryService repositoryService;

    @Override
    public void startFlow(AgLeave agLeave, LoginUser loginUser) {
        //int days = (int) ((agLeave.getLeaveEndtime().getTime() - agLeave.getLeaveStarttime().getTime()) / (1000*3600*24)) + 1;

        LocalDate startDate=agLeave.getLeaveStarttime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        LocalDate endDate=agLeave.getLeaveEndtime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        int days = (int) ChronoUnit.DAYS.between(startDate, endDate) + 1;

        String businesskey = "" + agLeave.getId();

        identityservice.setAuthenticatedUserId(agLeave.getApplicant());

        Map<String, Object> variables = new HashMap<String, Object>();
        variables.put("applyUser", agLeave.getApplicant());
        variables.put("auditUser",agLeave.getAuditing());
        variables.put("days",days);
        variables.put("leaveId", agLeave.getId());

       //Model modelData = repositoryService.getModel("90012");
        Model modelData = repositoryService.getModel("1270001");
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId(modelData.getDeploymentId()).singleResult();

        ProcessInstance instance=runtimeservice.startProcessInstanceById(processDefinition.getId(),businesskey,variables);
        String instanceid=instance.getId();
        agLeave.setProcessInstanceId(instanceid);
        Task task = taskService.createTaskQuery().processInstanceId(instance.getId()).taskAssignee(agLeave.getApplicant()).singleResult();

        agLeave.setTaskId(task.getId());

        this.baseMapper.updateById(agLeave);

        taskService.complete(task.getId(),variables);
    }

    @Override
    public IPage<AgLeave> taskList(List<String> roleList,Integer pageNo,Integer pageSize) {
        List<AgLeave> agLeaveList = new ArrayList<>();
        //Model modelData = repositoryService.getModel("90012");
        Model modelData = repositoryService.getModel("1270001");
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId(modelData.getDeploymentId()).singleResult();

        List<Task> taskList = taskService.createTaskQuery().processDefinitionId(processDefinition.getId()).taskCandidateGroupIn(roleList).listPage(pageNo-1,pageSize);
        Long total = taskService.createTaskQuery().processDefinitionId(processDefinition.getId()).taskCandidateGroupIn(roleList).count();
        taskList.forEach(task -> {
            String instanceId = task.getProcessInstanceId();
            AgLeave agLeave = agLeaveMapper.selectOne(new LambdaQueryWrapper<AgLeave>().eq(AgLeave::getProcessInstanceId,instanceId));
            if(null != agLeave) {
                agLeave.setTaskId(task.getId());
                agLeaveList.add(agLeave);
            }
        });
        IPage<AgLeave> page = new Page<>(pageNo,pageSize);
        page.setRecords(agLeaveList);
        page.setTotal(total);
        return page;
    }

    @Override
    public void complateTask(LoginUser loginUser, String taskId, Integer status, String memo, Integer go2xiaoj, String auditUser) {
//        taskService.claim(taskId,loginUser.getId());

        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        Map params = new HashMap(){{
            put("status", status);
            taskService.setVariable(taskId,"status", status);

            put("memo",memo);
            put("go2xiaoj", go2xiaoj);

            if(auditUser != null) {
                put("auditUser", auditUser);
                runtimeservice.setVariable(task.getExecutionId(),"auditUser",auditUser);
            }

            Integer days = (Integer) taskService.getVariable(taskId, "days");
            put("days", days);
        }};

        taskService.addComment(taskId,task.getProcessInstanceId(), JsonUtils.toJsonString(params));
        log.info("请销假流程params"+params);
        System.out.println("请销假流程params"+params);
       try{ taskService.complete(taskId,params);

       } catch (Exception e) {
           e.printStackTrace();
       }
    }

    @Override
    public void applyAgin(AgLeave agLeave) {
        Task task = taskService.createTaskQuery().processInstanceId(agLeave.getProcessInstanceId()).taskAssignee(agLeave.getApplicant()).singleResult();
        agLeave.setTaskId(task.getId());
        agLeaveMapper.updateById(agLeave);

        Map<String, Object> variables = new HashMap<String, Object>();
        variables.put("status",1);
        taskService.complete(task.getId(),variables);
    }

    @Override
    public IPage<AgLeave> myApplyList(Page<AgLeave> page, LoginUser user, AgLeave agLeave) {
        return this.baseMapper.myApplyList(page, user, agLeave);
    }

    @Override
    public IPage<AgLeave> myTodoTasks(Page<AgLeave> page, LoginUser user, AgLeave agLeave) {
        return this.baseMapper.myTodoTasks(page, user, agLeave);
    }

    @Override
    public IPage<AgLeave> myDoneTasks(Page<AgLeave> page, LoginUser user, AgLeave agLeave) {
        return this.baseMapper.myDoneTasks(page, user, agLeave);
    }

    @Override
    public void execute(DelegateExecution execution) {
        String processInstanceId = execution.getProcessInstanceId();
        AgLeave agLeave = agLeaveService.getOne(new QueryWrapper<AgLeave>().eq("process_instance_id", processInstanceId));
        String DLM = agLeave.getApplicant();
        Map<String, Object> map = new HashMap() {{
            put("DLM", DLM);
        }};

        // 调用云平台理达军网接口，用户信息中的卡号换取personCode； 再调用理达的web服务设置门禁权限
        //1.户信息中的卡号换取personCode
        String personCode = restTemplate.getForObject("http://26.29.23.18:18080/sdata/rest/service/dataapi/rest/507aa702-2d51-47f1-b711-3d483e2d7777", String.class, map);
        //2.调用理达的web服务设置门禁权限
        try {
            //获取全部权限
            List<GroupPO> securityGroupIDs = lidaService.doGetAccessSecurityGroups();
            //先删后增
            List list = lidaService.doOperatePersonSecurityGroupID(personCode, securityGroupIDs);
            if (list!=null&&list.size()>=1){
                String applicant = agLeave.getApplicant();
                agLeave.setBeizhu("申请人:"+applicant+"+卡号"+personCode+"请假成功");
                agLeaveService.updateById(agLeave);
            }else {
                agLeave.setBeizhu("请假失败");
                agLeaveService.updateById(agLeave);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
